﻿using Magicodes.ExporterAndImporter.Core;
using Magicodes.ExporterAndImporter.Core.Extension;
using Magicodes.ExporterAndImporter.Excel;
using Mapster;
using Microsoft.Extensions.Configuration;
using NP.BPMReportPlatform.DBHelper;
using NP.BPMReportPlatform.Entities.BPM_Business;
using NP.BPMReportPlatform.HR.Dto;
using NP.BPMReportPlatform.SystemSettings.Dto;
using NPOI.HPSF;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;

namespace NP.BPMReportPlatform.SystemSettings
{
    /// <summary>
    /// KeyValues字典表 配置接口服务
    /// </summary>
    public class KeyValuesConfigurationAppService : BPMReportPlatformAppService, IKeyValuesConfigurationAppService
    {
        private readonly SqlSugarClient _dbBusiness;
        private readonly IExcelImporter _importer;

        public KeyValuesConfigurationAppService(ISqlSugarAppService sqlSugarAppService, IConfiguration configuration, IExcelImporter importer)
        {
            _dbBusiness = sqlSugarAppService.GetBusinessInstance();
            _importer = importer;
        }

        /// <summary>
        /// 查询数据
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PagedResultDto<KeyValuesConfigurationOutput>> GetAllAsync(KeyValuesConfigurationInput input)
        {
            RefAsync<int> totalCount = 0;

            var listViewDto = await _dbBusiness.Queryable<KeyValues>()
                .WhereIF(!string.IsNullOrWhiteSpace(input.Code), x => x.Code.Contains(input.Code))
                .WhereIF(!string.IsNullOrWhiteSpace(input.Name), x => x.Name.Contains(input.Name))
                .WhereIF(!string.IsNullOrWhiteSpace(input.CatalogCode), x => x.CatalogCode.Contains(input.CatalogCode))
                .WhereIF(!string.IsNullOrWhiteSpace(input.CatalogName), x => x.CatalogName.Contains(input.CatalogName))
                .WhereIF(!string.IsNullOrWhiteSpace(input.ParentCode), x => x.ParentCode.Contains(input.ParentCode))
                .OrderBy(x=>x.ParentCode,OrderByType.Asc)
                .ToPageListAsync(input.PageIndex, input.PageSize, totalCount);
            var mapperList = listViewDto.Adapt<List<KeyValuesConfigurationOutput>>();

            //返回结果
            return new PagedResultDto<KeyValuesConfigurationOutput>()
            {
                TotalCount = totalCount,
                Items = mapperList
            };
        }

        /// <summary>
        /// 保存配置
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task SaveAsync(SaveKeyValuesConfigurationInput input)
        {
            var mapperInput = input.Adapt<KeyValues>();
            if (mapperInput.Id != null)
            {
                var currentData = _dbBusiness.Queryable<KeyValues>().Where(x => x.Code == input.Code && x.CatalogCode == input.CatalogCode)
                      .WhereIF(!string.IsNullOrWhiteSpace(input.ParentCode), x => x.ParentCode == input.ParentCode)
                      .WhereIF(string.IsNullOrWhiteSpace(input.ParentCode), x => string.IsNullOrWhiteSpace(x.ParentCode))
                      .WhereIF(input.Id != Guid.Empty, x => x.Id != input.Id)
                      .First();
                if (!string.IsNullOrWhiteSpace(currentData?.Code))
                {
                    throw new Exception($"编码+父级编码+分类编码已存在！不能重发添加");
                }
                await _dbBusiness.Updateable(mapperInput).ExecuteCommandAsync();
            }
            else
            {
                var currentData = _dbBusiness.Queryable<KeyValues>().Where(x => x.Code == input.Code && x.CatalogCode == input.CatalogCode)
                      .WhereIF(!string.IsNullOrWhiteSpace(input.ParentCode), x => x.ParentCode == input.ParentCode)
                      .WhereIF(string.IsNullOrWhiteSpace(input.ParentCode), x => string.IsNullOrWhiteSpace(x.ParentCode))
                      .First();
                if (!string.IsNullOrWhiteSpace(currentData?.Code))
                {
                    throw new Exception($"编码+父级编码+分类编码已存在！不能重发添加");
                }
                mapperInput.Id = Guid.NewGuid();
                await _dbBusiness.Insertable(mapperInput).ExecuteCommandAsync();
            }
        }

        /// <summary>
        /// 删除配置
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task DeleteAsync(string id)
        {
            var cnt = await _dbBusiness.Deleteable<KeyValues>().Where(x => x.Id.Equals(id)).ExecuteCommandAsync();
        }

        /// <summary>
        /// 批量导入Excel
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public async Task<ImportResultExt<ImportKeyValuesTemplate>> ImporterExcel(byte[] bytes)
        {
            Stream stream = new MemoryStream(bytes);
            var rst = await _importer.Import<ImportKeyValuesTemplate>(stream);
            var importData = rst.Data;
            if (!rst.HasError)
            {
                int index = 1;
                List<KeyValues> list = new List<KeyValues>();
                // 获取基础连带数据
                foreach (var item in importData)
                {
                    var currentData = _dbBusiness.Queryable<KeyValues>().Where(x => x.Code == item.Code && x.CatalogCode == item.CatalogCode)
                        .WhereIF(!string.IsNullOrWhiteSpace(item.ParentCode),x=>x.ParentCode==item.ParentCode)
                        .WhereIF(string.IsNullOrWhiteSpace(item.ParentCode), x => string.IsNullOrWhiteSpace(x.ParentCode))
                        .First();
                    if (!string.IsNullOrWhiteSpace(currentData?.Code))
                    {
                        rst.Exception = new Exception($"第{index}行，编码+父级编码+分类编码已存在！");
                        break;
                    }
                    KeyValues keyValues = new KeyValues()
                    {
                        Id = Guid.NewGuid(),
                        Code = item.Code,
                        Name = item.Name,
                        ParentCode = item.ParentCode,
                        CatalogCode = item.CatalogCode,
                        CatalogName = item.CatalogName,
                        Sort= Convert.ToInt32(item.Sort),
                        Remark = item.Remark,
                        IsDelete =false
                    };

                    list.Add(keyValues);
                }
                if (rst.Exception == null)
                {
                    await _dbBusiness.Insertable(list).ExecuteCommandAsync();
                }
            }
            var resp = new ImportResultExt<ImportKeyValuesTemplate>()
            {
                Data = importData,
                Exception = rst.Exception,
                RowErrors = rst.RowErrors,
                TemplateErrors = rst.TemplateErrors
            };
            return resp;
        }
    }
}
